package ui;

// 自定义包导入（model、service、factory、util）
import factory.ServiceFactory;
import model.Order;
import model.Order.OrderStatus;
import model.RedWine;
import model.User;
import service.OrderService;
import service.RedWineService;
import service.UserService;
import util.InputValidator;

// Java标准库导入（java.util）
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;

public class UserUI extends UI { // 普通用户界面 完成人：邓亦明、尹佳杨 7/5
    private UserService userService = ServiceFactory.getUserService();
    private OrderService orderService = ServiceFactory.getOrderService(); // 获取 OrderService 实例
    private RedWineService redWineService = ServiceFactory.getRedWineService();

    private User currentUser;

    public UserUI(User user) {
        this.currentUser = user;
    }

    @Override
    public void show() { //覆写父类show()方法
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("红酒销售管理系统 - 普通用户权限");
            System.out.println("1. 修改本人信息");
            System.out.println("2. 红酒信息查询");
            System.out.println("3. 余额充值");
            System.out.println("4. 红酒购买"); //
            System.out.println("5. 本人订单管理"); // 新增功能
            System.out.println("0. 退出");
            System.out.print("请选择功能: ");
            String choice = scanner.nextLine();
            if ("1".equals(choice)) {
                updateSelfInfo(scanner); // 修改本人信息
            } else if ("2".equals(choice)) {
                redWineManageMenu(scanner); // 与管理员一致的红酒信息查询
            } else if ("3".equals(choice)) {
                recharge(scanner); // 新增充值功能
            } else if ("4".equals(choice)) { // 处理红酒购买
                purchaseRedWine(scanner);
            } else if ("5".equals(choice)) {
                orderManagementMenu(scanner); // 新增订单管理菜单
            } else if ("0".equals(choice)) {
                break;
            }
        }
    }


        // 新增：订单管理菜单
    private void orderManagementMenu(Scanner scanner) {
        while (true) {
            System.out.println("---- 本人订单管理 ----");
            System.out.println("1. 所有订单");
            System.out.println("2. 未付款订单");
            System.out.println("3. 已付款订单");
            System.out.println("4. 待收货订单");
            System.out.println("5. 已完成订单");
            System.out.println("0. 返回上级菜单");
            System.out.print("请选择: ");
            String op = scanner.nextLine();
            
            if ("1".equals(op)) {
                listAllOrders(scanner);
            } else if ("2".equals(op)) {
                listUnpaidOrders(scanner);
            } else if ("3".equals(op)) {
                listPaidOrders(scanner);
            } else if ("4".equals(op)) {
                listShippingOrders(scanner);
            } else if ("5".equals(op)) {
                listCompletedOrders();
            } else if ("0".equals(op)) {
                break;
            }
        }
    }

    // 新增：列出所有订单
    private void listAllOrders(Scanner scanner) {
        List<Order> orders = getCurrentUserOrders();
        if (orders.isEmpty()) {
            System.out.println("您还没有任何订单！");
            return;
        }
        printOrderList(orders);
    }

    // 新增：列出未付款订单并提供操作
    private void listUnpaidOrders(Scanner scanner) {
        List<Order> unpaidOrders = getCurrentUserOrders().stream()
                .filter(o -> o.getStatus() == OrderStatus.未付款)
                .collect(Collectors.toList());
        
        if (unpaidOrders.isEmpty()) {
            System.out.println("没有未付款订单！");
            return;
        }
        
        printOrderList(unpaidOrders);
        
        while (true) {
            System.out.println("1. 付款");
            System.out.println("2. 取消订单");
            System.out.println("0. 返回");
            System.out.print("请选择操作: ");
            String choice = scanner.nextLine();
            
            if ("1".equals(choice)) {
                payForOrder(scanner);
            } else if ("2".equals(choice)) {
                cancelOrder(scanner);
            } else if ("0".equals(choice)) {
                break;
            }
        }
    }

    // 新增：付款操作
    private void payForOrder(Scanner scanner) {
        int code = InputValidator.getValidPositiveInt(scanner, "请输入要付款的订单标识码: ", "标识码");
        
        // 获取该标识码的所有订单
        List<Order> ordersToPay = getOrdersByCode(code).stream()
                .filter(o -> o.getStatus() == OrderStatus.未付款)
                .collect(Collectors.toList());
        
        if (ordersToPay.isEmpty()) {
            System.out.println("未找到该标识码的未付款订单！");
            return;
        }
        
        // 计算总金额
        double totalAmount = calculateTotalAmount(ordersToPay);
        
        System.out.printf("订单总金额: %.2f，您的余额: %.2f%n", totalAmount, currentUser.getBalance());
        
        if (currentUser.getBalance() < totalAmount) {
            System.out.println("余额不足，无法付款！");
            return;
        }
        
        // 扣款并更新订单状态
        if (userService.deductBalance(currentUser, totalAmount)) {
            for (Order order : ordersToPay) {
                order.setStatus(OrderStatus.已付款);
                orderService.updateOrder(order);
            }
            System.out.println("付款成功！订单状态已更新为已付款。");
            System.out.printf("当前余额: %.2f%n", currentUser.getBalance());
        } else {
            System.out.println("付款失败，请联系管理员！");
        }
    }

    // 新增：取消订单操作
    private void cancelOrder(Scanner scanner) {
        int code = InputValidator.getValidPositiveInt(scanner, "请输入要取消的订单标识码: ", "标识码");
        
        // 获取该标识码的所有订单
        List<Order> ordersToCancel = getOrdersByCode(code);
        
        if (ordersToCancel.isEmpty()) {
            System.out.println("未找到该标识码的订单！");
            return;
        }
        
        // 计算总金额（仅已付款订单需要退款）
        double refundAmount = ordersToCancel.stream()
                .filter(o -> o.getStatus() == OrderStatus.已付款)
                .mapToDouble(this::calculateOrderAmount)
                .sum();
        
        // 恢复库存（所有订单都需要恢复）
        for (Order order : ordersToCancel) {
            RedWine redWine = redWineService.findById(order.getRedWineId());
            if (redWine != null) {
                redWine.setStock(redWine.getStock() + order.getQuantity());
                redWineService.updateRedWine(redWine);
            }
            
            // 删除订单
            orderService.deleteOrder(order.getOrderId());
        }
        
        // 退款（仅已付款订单）
        if (refundAmount > 0) {
            currentUser.setBalance(currentUser.getBalance() + refundAmount);
            if (userService.updateUser(currentUser)) {
                System.out.printf("已退款: %.2f%n", refundAmount);
            } else {
                System.out.println("退款失败，请联系管理员！");
            }
        }
        
        System.out.println("订单已取消！");
        System.out.printf("当前余额: %.2f%n", currentUser.getBalance());
    }

    // 新增：列出已付款订单并提供操作
    private void listPaidOrders(Scanner scanner) {
        List<Order> paidOrders = getCurrentUserOrders().stream()
                .filter(o -> o.getStatus() == OrderStatus.已付款)
                .collect(Collectors.toList());
        
        if (paidOrders.isEmpty()) {
            System.out.println("没有已付款订单！");
            return;
        }
        
        printOrderList(paidOrders);
        
        while (true) {
            System.out.println("1. 取消订单");
            System.out.println("0. 返回");
            System.out.print("请选择操作: ");
            String choice = scanner.nextLine();
            
            if ("1".equals(choice)) {
                cancelOrder(scanner);
            } else if ("0".equals(choice)) {
                break;
            }
        }
    }

    // 新增：列出待收货订单
    private void listShippingOrders(Scanner scanner) {
        List<Order> shippingOrders = getCurrentUserOrders().stream()
                .filter(o -> o.getStatus() == OrderStatus.待收货)
                .collect(Collectors.toList());
        
        if (shippingOrders.isEmpty()) {
            System.out.println("没有待收货订单！");
            return;
        }
        
        printOrderList(shippingOrders);
        
        while (true) {
            System.out.println("1. 确认收货");
            System.out.println("0. 返回");
            System.out.print("请选择操作: ");
            String choice = scanner.nextLine();
            
            if ("1".equals(choice)) {
                confirmReceipt(scanner);
            } else if ("0".equals(choice)) {
                break;
            }
        }
    }

    // 新增：列出已完成订单
    private void listCompletedOrders() {
        List<Order> completedOrders = getCurrentUserOrders().stream()
                .filter(o -> o.getStatus() == OrderStatus.已完成)
                .collect(Collectors.toList());
        
        if (completedOrders.isEmpty()) {
            System.out.println("没有已完成订单！");
            return;
        }
        
        printOrderList(completedOrders);
    }

    // 新增：获取当前用户的所有订单
    private List<Order> getCurrentUserOrders() {
        return orderService.findAll().stream()
                .filter(o -> o.getUserId() == currentUser.getUserId())
                .collect(Collectors.toList());
    }

    // 新增：根据标识码获取订单
    private List<Order> getOrdersByCode(int code) {
        return orderService.findAll().stream()
                .filter(o -> o.getCode() == code && o.getUserId() == currentUser.getUserId())
                .collect(Collectors.toList());
    }

    private void updateSelfInfo(Scanner scanner) { // 修改本人信息
        System.out.print("新用户名(" + currentUser.getUsername() + "): ");
        String username = scanner.nextLine();
        if (!username.isEmpty()) {
            // 检查新用户名是否已被其他用户使用
            java.util.List<User> existUsers = userService.findByUsername(username);
            boolean isUsed = false;
            for (User u : existUsers) {
                if (u.getUserId() != currentUser.getUserId()) {
                    isUsed = true;
                    break;
                }
            }
            if (isUsed) {
                System.out.println("用户名已被其他用户使用！");
                return;
            }
            currentUser.setUsername(username);
        }
        System.out.print("新密码(留空不变): ");
        String password = scanner.nextLine();
        if (!password.isEmpty())
            currentUser.setPassword(password);
        System.out.print("新地址(" + currentUser.getAddress() + "): ");
        String address = scanner.nextLine();
        if (!address.isEmpty())
            currentUser.setAddress(address);
        System.out.print("新电话(" + currentUser.getPhone() + "): ");
        String phone = scanner.nextLine();
        if (!phone.isEmpty())
            currentUser.setPhone(phone);
        // 不允许修改余额和用户ID
        if (userService.updateUser(currentUser)) {
            System.out.println("修改成功！");
        } else {
            System.out.println("修改失败！");
        }
    }

    // 与管理员一致的红酒信息管理菜单（仅查询相关功能）
    private void redWineManageMenu(Scanner scanner) { //
        while (true) {
            System.out.println("---- 红酒信息查询 ----");
            System.out.println("1. 查询所有红酒");
            System.out.println("2. 筛选红酒");
            System.out.println("0. 返回上级菜单");
            System.out.print("请选择: ");
            String op = scanner.nextLine();
            if ("1".equals(op)) {
                listRedWines(); //
            } else if ("2".equals(op)) {
                super.filterRedWine(scanner); // 调用父类方法
            } else if ("0".equals(op)) {
                break;
            }
        }
    }

    private void recharge(Scanner scanner) {
        // 充值前需要验证用户身份
        System.out.println("为了安全起见，充值前需要验证您的身份信息：");
        
        // 使用InputValidator工具类进行用户名校验
        String username = InputValidator.getValidNonEmptyString(scanner, "请输入用户名进行身份验证: ", "用户名");
        
        // 使用InputValidator工具类进行密码校验
        String password = InputValidator.getValidNonEmptyString(scanner, "请输入密码: ", "密码");
        
        // 验证用户名和密码是否与当前用户匹配
        if (!currentUser.getUsername().equals(username) || !currentUser.getPassword().equals(password)) {
            System.out.println("用户名或密码错误，充值失败！");
            return;
        }
        
        // 使用InputValidator工具类进行充值金额校验
        double amount = InputValidator.getValidPositiveDouble(scanner, "请输入充值金额: ", "充值金额");
        
        // 验证通过后为当前用户充值
        currentUser.setBalance(currentUser.getBalance() + amount);
        if (userService.updateUser(currentUser)) {
            System.out.println("充值成功，当前余额：" + currentUser.getBalance());
        } else {
            System.out.println("充值失败！");
        }
    }

    // 红酒购买功能
    private void purchaseRedWine(Scanner scanner) { //
        // 1. 检查用户地址和电话信息
        String address = currentUser.getAddress();
        String phone = currentUser.getPhone();

        if (address == null || address.trim().isEmpty() || phone == null || phone.trim().isEmpty()) { //
            System.out.println("请完善地址与电话信息后才能购买红酒！"); //
            System.out.println("当前地址：" + (address == null || address.trim().isEmpty() ? "未填写" : address)); //
            System.out.println("当前电话：" + (phone == null || phone.trim().isEmpty() ? "未填写" : phone)); //
            return; // 退出购买流程
        }

        System.out.println("您的当前地址：" + address); //
        System.out.println("您的当前电话：" + phone); //

        // 2. 输入线上标识 (1/0)
        int onlineFlag;
        while (true) {
            System.out.print("请输入线上标识 (1代表线上购买，0代表线下购买): "); //
            String onlineStr = scanner.nextLine(); //
            try {
                onlineFlag = Integer.parseInt(onlineStr); //
                if (onlineFlag == 0 || onlineFlag == 1) { //
                    break; // 输入有效，跳出循环
                } else {
                    System.out.println("输入无效，请输入1或0。"); //
                }
            } catch (NumberFormatException e) {
                System.out.println("输入格式错误，请输入数字1或0。"); //
            }
        }
        System.out.println("您选择了：" + (onlineFlag == 1 ? "线上购买" : "线下购买")); //

        // 用于存储用户购买的红酒及数量
        // Map<红酒ID, 购买数量>
        Map<Integer, Integer> purchaseItems = new HashMap<>(); //
        double totalAmount = 0.0; // 本次购买的总金额

        System.out.println("\n请输入您想购买的红酒ID和数量，输入红酒ID为0时结束购买。"); //
        while (true) {
            System.out.print("请输入红酒ID (输入0结束): "); //
            String redWineIdStr = scanner.nextLine(); //
            int redWineId;
            try {
                redWineId = Integer.parseInt(redWineIdStr); //
            } catch (NumberFormatException e) {
                System.out.println("红酒ID格式错误，请输入数字。"); //
                continue;
            }

            if (redWineId == 0) { //
                break; // 用户输入0，结束购买
            }

            // 查询红酒是否存在
            RedWine redWine = redWineService.findById(redWineId); //
            if (redWine == null) { //
                System.out.println("未找到ID为 " + redWineId + " 的红酒，请确认后重新输入。"); //
                continue;
            }

            // 检查红酒库存
            if (redWine.getStock() <= 0) { //
                System.out.println("红酒: " + redWine.getName() + " (ID: " + redWineId + ") 库存不足，无法购买。"); //
                continue;
            }

            System.out.print("请输入购买数量: "); //
            String quantityStr = scanner.nextLine(); //
            int quantity;
            try {
                quantity = Integer.parseInt(quantityStr); //
            } catch (NumberFormatException e) {
                System.out.println("购买数量格式错误，请输入数字。"); //
                continue;
            }

            if (quantity <= 0) { //
                System.out.println("购买数量必须大于0。"); //
                continue;
            }

            if (quantity > redWine.getStock()) { //
                System.out.println("红酒: " + redWine.getName() + " (ID: " + redWineId + ") 库存仅剩 " + redWine.getStock()
                        + "，您购买的数量超过库存。"); //
                continue;
            }

            // 将购买项添加到列表中
            // 如果已经添加过该红酒，则累加数量
            purchaseItems.put(redWineId, purchaseItems.getOrDefault(redWineId, 0) + quantity); //
            totalAmount += redWine.getPrice() * quantity; //
            System.out.println(
                    "已添加: " + redWine.getName() + " x " + quantity + "。当前总金额: " + String.format("%.2f", totalAmount)); //
        }

        if (purchaseItems.isEmpty()) { //
            System.out.println("您没有选择任何红酒，购买流程结束。"); //
            return;
        }

        // 打印购买清单（可选，用于调试和用户确认）
        System.out.println("\n--- 您的购买清单 ---"); //
        for (Map.Entry<Integer, Integer> entry : purchaseItems.entrySet()) { //
            int redWineId = entry.getKey(); //
            int quantity = entry.getValue(); //
            RedWine redWine = redWineService.findById(redWineId); // 重新获取红酒信息以显示名称和价格
            if (redWine != null) { //
                System.out.printf("红酒ID: %d, 名称: %s, 数量: %d, 单价: %.2f, 小计: %.2f\n", //
                        redWineId, redWine.getName(), quantity, redWine.getPrice(), redWine.getPrice() * quantity);
            }
        }
        System.out.println("总计金额: " + String.format("%.2f", totalAmount)); //

        // 调用 OrderService 处理订单创建和库存更新
        int orderCode = orderService.processRedWinePurchase(currentUser, purchaseItems, onlineFlag);

        if (orderCode == -1) {
            System.out.println("红酒购买订单创建失败，请联系管理员。");
            return;
        }
        System.out.println("订单已成功创建！本次订单的标识码为：" + orderCode);

        // 2. 提示是否立即付款
        System.out.print("是否立即付款？(1=是, 0=否): ");
        String payChoiceStr = scanner.nextLine();
        int payChoice;
        try {
            payChoice = Integer.parseInt(payChoiceStr);
        } catch (NumberFormatException e) {
            System.out.println("输入格式错误，默认不立即付款。");
            payChoice = 0;
        }

        if (payChoice == 1) { // 立即付款
            if (currentUser.getBalance() >= totalAmount) {
                // 扣除余额
                if (userService.deductBalance(currentUser, totalAmount)) {
                    // 更新订单状态为“已付款”
                    if (orderService.updateOrdersStatusByCode(orderCode, Order.OrderStatus.已付款)) {
                        System.out.println("付款成功！您的余额为：" + String.format("%.2f", currentUser.getBalance()));
                    } else {
                        System.out.println("付款成功但订单状态更新失败，请联系管理员！");
                        // 考虑此处如果更新失败是否需要回滚余额？目前的事务模型下，需要更复杂的逻辑。
                        // 当前设定是：DAO层负责自己内部的事务。这里UI协调Service的两个独立操作。
                    }
                } else {
                    System.out.println("扣除余额失败，请联系管理员！");
                }
            } else {
                System.out.println("余额不足！当前余额：" + String.format("%.2f", currentUser.getBalance()) + "，需要支付："
                        + String.format("%.2f", totalAmount));
                System.out.println("请先充值或稍后在'本人订单管理'中付款。");
            }
        } else {
            System.out.println("您选择不立即付款。订单已创建，状态为“未付款”，您可以在“本人订单管理”中查看并支付。");
        }
    }

    // 新增：确认收货操作
    private void confirmReceipt(Scanner scanner) {
        int code = InputValidator.getValidPositiveInt(scanner, "请输入要确认收货的订单标识码: ", "标识码");
        
        // 获取该标识码的所有待收货订单
        List<Order> ordersToConfirm = getOrdersByCode(code).stream()
                .filter(o -> o.getStatus() == OrderStatus.待收货)
                .collect(Collectors.toList());
        
        if (ordersToConfirm.isEmpty()) {
            System.out.println("未找到该标识码的待收货订单！");
            return;
        }
        
        System.out.println("找到 " + ordersToConfirm.size() + " 个待收货订单：");
        printOrderList(ordersToConfirm);
        
        System.out.print("确认收货以上所有订单吗？(y/n): ");
        String confirmation = scanner.nextLine().trim();
        if (!"y".equalsIgnoreCase(confirmation)) {
            System.out.println("取消确认收货操作。");
            return;
        }
        
        int confirmedCount = 0;
        
        // 更新所有匹配订单的状态为已完成
        for (Order order : ordersToConfirm) {
            order.setStatus(OrderStatus.已完成);
            if (orderService.updateOrder(order)) {
                confirmedCount++;
                System.out.println("订单ID " + order.getOrderId() + " 已确认收货！");
            } else {
                System.out.println("订单ID " + order.getOrderId() + " 确认收货失败！");
            }
        }
        
        System.out.println("=== 确认收货操作完成 ===");
        System.out.println("成功确认收货订单数: " + confirmedCount + "/" + ordersToConfirm.size());
        
        if (confirmedCount == ordersToConfirm.size()) {
            System.out.println("所有订单已成功确认收货！");
        } else if (confirmedCount > 0) {
            System.out.println("部分订单确认收货成功，请检查失败的订单或联系管理员。");
        } else {
            System.out.println("所有订单确认收货失败，请联系管理员！");
        }    }
}